home *** CD-ROM | disk | FTP | other *** search
- name msxgri
- ; File MSXGRI.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Grid Compass dependent file for MS-DOS Kermit
- ; Use with msugri.asm keyboard translator file.
- ; Edit history
- ; 2 March 1991 version 3.10
- ; Last edit:
- ; 2 March 1991
- ; Dec. 7, 1990. Put modem in verbose mode at startup.
- ; Change machnm from GRID to GRiD.
- ; Nov. 27, 1990. Add call to getbaud in serini.
- ; Nov. 24, 1990. Remove reference to prserr to make link happy.
- ; Nov. 21, 1990. Fix so both serial and modem drivers need not be loaded
- ; if they are not used. [jan]
- ; October 1990. Cosmetic fixes.
- ; August 1990. Select tek enable/ disable in termtb
- ; 22 february 1990 Fix up baud setting and and string parsing
- ; procedurs [jan]
- ; 23 January 1990. Version 3. Fix up comnd calls. Chance PRTCHR so
- ; clc for character, stc for no character. clc in OUTPRT. Include
- ; baud table and portval. Add BAUDST from MSXIBM.ASM. Zap DODISK. [jan]
- ; 3 February 1989.
- ; Call "call cmblnk" call call to tekcls so tek screen is cleared
- ; even if it's not initialized
- ; Take out II in machnm since this also works on 1101 [jan]
- ; 5 January 1989. Fix up SERINT, SERINI, SERRST, and SENDBR.
- ; Implement GETMODEM and SERHNG. Send 'ATE1' to modem in LCLINI. [jan]
- ; 13 Dec 1988 Move screen clear and terminal type toggling to this file.
- ; Do other small cleanups. [jrd]
- ;
- ; John Nyenhuis Purdue University School of Electrical Engineering
- ; West Lafayette IN 47907 (317)494-3524 nyenhuis@ecn.purdue.edu
- ; November 1988
- ; Fix up for Tektronix emulation
- ; User can specify screen size by set term 112x or set term 113x
- ; Call sbrk to get memory for Tektronix and ascii screen saves
- ; enable automatic entry into Tektronix emulator
- ; Most characters are now written to screen through bios rather than with DOS
- ; keyboard is checked once each 8 read of serial port for added speed
- ; Xon/Xoff flow control enabled
- ; vt52 terminal emulation taken out (all it did was to not restore the cursor)
- ;
- ; 1 July 1988 Version 2.31
- ; 12 June 1988 Add error recovery if serial port fails to initialize, reduce
- ; serial port buffer to 1000 bytes. [jrd]
- ; 11 Jan 1988 Add 2.30 features. [jrd]
- ; 1 Jan 1988 version 2.30
- ;
- ; Jim Noble
- ; Planning Research Corporation
- ; 1500 Planning Research Drive
- ; Mail Stop 5S3
- ; McLean, VA 22102
- ; May, 1985
- ; Add global entry point vtstat for use by Status in mssset.
- ; Added register save/restore in procedure getbaud.
- ; Joe R. Doupnik 12 March 1986
- ; Add global procedures ihosts and ihostr to handle host initialization
- ; when packets are to be sent or received by us,resp. 24 March 1986
- ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low
- ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd]
- ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen
- ; to a file. Just does a beep for now. 13 April 1986 [jrd]
- ; In proc Outchr add override of xon from chkxon sending routine.
- ; This makes a hand typed Xoff supress the xon flow control character sent
- ; automatically as the receiver buffer empties. 20 April 1986 [jrd]
-
-
- saveregs macro
- push ax
- push bx
- push cx
- push dx
- push es
- push di
- push si
- push ds
- pushf
- endm
-
- restoreregs macro
- popf
- pop ds
- pop si
- pop di
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- endm
-
- ;; below 40 publics are the minimum necessary
- public baudst,ihostr,bdtab,getbaud,chrout
- public pcwait,putmod,serrst,trnprs,prtchr
- public poscur,outchr,dtrlow,vts,puthlp
- public vtstat,coms,cquery,ctlu,shomodem
- public portval,getmodem,term,dumpscr,cmblnk
- public cquit,locate,clearl,machnam,lclini
- public sendbl,comptab,sendbr,clrmod,cstatus
- public termtb,serhng,clrbuf,beep, serini
- ;;additional system dependent publics
- public klogon,kdos,snull,klogof
- public bigscreen ; bigscreen=1 if it's big [jan]
- public termtog ; toggle terminal types [jan]
- public kclrscn, getflgs, setchtab
-
- cmcfm equ cmeol ; equates to account for 3.0
- cmtxt equ cmline ; names changes in
- cmfile equ cmword ; mssdef.h
-
- baudsiz equ 18 ; entries in baud table
- false equ 0
- true equ 1
- print_out equ 05h ; dos function to print to printer
- prtscr equ 80h ; print screen pressed
-
- gbuflen equ 1000 ; max bytes grid internal buffer holds
- mntrgh equ gbuflen/2 ; High point = 1/2 of buffer full.
- mntrgl equ gbuflen/4 ; Low point = 1/4 buffer full. [jrd]
-
- CLK_INT equ 1ch*4 ; clock interrupt
- gserial equ 81h ; grid serial port interrupt
- gmodem equ 82h ; grid modem port interrupt
- ginit equ 0 ; function 0 - initialize port
- gread equ 1 ; function 1 - read data
- gwrite equ 2 ; function 2 - write data
- gwcmd equ 4 ; function 4 - write command
- grstat equ 5 ; function 5 - read status
- gflush equ 6 ; function 6 - buffer flush
- ggbaud equ 7 ; function 7 - get baud
- gsbaud equ 8 ; function 8 - set baud
- gspar equ 9 ; function 9 - set parity
- gsdata equ 10 ; function 10 - set data bits
- gssbit equ 11 ; function 11 - set stop bits
- gbufass equ 12 ; function 12 - buffer assign
- gcharto equ 13 ; function 13 - set character timeout
- gcts equ 19 ; function 19 - clear to send timeout
- gbrkon equ 0effH ; function 14 - set break on
- gbrkoff equ 0e00H ; function 14 - set break off
- scnstrt equ 400h ; starting address of screen area (page 0)
- maxscnwrds equ 256*32 ; max number of words in screen memory area
- tekonnum equ 18 ; enable tek auto entry
- tekoffnum equ 19
- ttbig equ 12 ;big screen
- ttsmall equ 23 ;small screen
-
- data segment public 'data'
- extrn flags:byte, trans:byte
-
- extrn dmpname:byte
- extrn kbdflg:byte, rxtable:byte
- extrn tekflg:byte ; used in msggri [jan]
- extrn denyflg:word ; controls tek autoentry etc
- extrn dosnum:word
- extrn repflg:byte, diskio:byte ; for replay feature
- extrn kbdflg:byte ; in telnet
-
-
- ; structure for status information table sttab.
- stent struc
- sttyp dw ? ; type (actually routine to call)
- msg dw ? ; message to print
- val2 dw ? ; needed value: another message, or tbl addr
- tstcel dw ? ; address of cell to test, in data segment
- basval dw 0 ; base value, if non-zero
- stent ends
-
- ; table with datacomm status for the status command
- vtstbl stent <srchkw,tekstatustxt,termtb,tekbyte> ; tell tek able/disable
- stent <srchkw,screenstatustxt,termtb,screenbyte> ; tell screen size
- dw 0 ; end of table
-
-
-
- tekstatustxt db 'Tek Auto Entry: $'
- tekbyte db tekonnum ; tek auto entry code
- screenstatustxt db 'Screen Size: $'
- screenbyte db ttsmall
- prtrdy db true ; when false, exit connect mode
- machnam db 'GRiD_COMPASS$'
- msmsg1 db cr,lf,' Modem is not ready: DSR is off$'
- msmsg2 db cr,lf,' Modem is ready: DSR is on$'
- msmsg3 db cr,lf,' no Carrier Detect: CD is off$'
- msmsg4 db cr,lf,' Carrier Detect: CD is on$'
- msmsg5 db cr,lf,' no Clear To Send: CTS is off$'
- msmsg6 db cr,lf,' Clear To Send: CTS is on$'
- msmsg7 db cr,lf,' Modem is not used by the Network$'
-
-
- mdmhand db 0 ;used by showmodem
- mdmstr db 'ATE1Q0V1S7=25,',cr,lf ;init modem string
- mdmstrlen equ $-mdmstr ;length of modem string
-
- ;;new stuff to scan escape sequences from comm port [jan]
- stringtab dw tekst1,tekst2 ; strings for matching
- numstrings equ 2 ; number of strings to match
- disptab dw toteknoplay,totekplay ; dispatch table
- tekst1 db escape,'[?38h',0 ;1st string to get into tek mode [jan]
- tekst2 db escape,FF,0 ;2nd string to get into tek mode [jan]
-
- stringchekbuff db 16 dup (0)
- stringchekcnt dw 0 ;characters already in buffer
- matchsofar dw false ; no match yet
- match dw 0
- playem db false ;don't play back switch characters
- ; end of data for string scanning
-
-
- scnwrds dw 240*20 ;words in small screen [jan]
- scrsavseg dw ? ;segment for screen save [jan]
- bigscreen db 0 ;=1 for big [jan]
- prevport db 86 ;port number on previous connect
- portbusy db 0 ;serial port not yet busy
- save_ax dw ? ;temp location to save ax
- save_ds dw ? ;temp location to save ds
- curini db 0 ; [gaw@prc]
- cursav db ESCAPE,'[s','$' ; [gaw@prc]
- curres db ESCAPE,'[u','$' ; [gaw@prc]
- curon db ESCAPE,'[3;3z','$' ; [gaw@prc]
- curoff db ESCAPE,'[3;4z','$' ; [gaw@prc]
-
- erms20 db cr,lf,'?Warning: System has no disk drives$'
- erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
- badbd db cr,lf,'Unimplemented baud rate$'
- crlf db cr,lf,'$'
- comphlp db cr,lf,'1 (SERIAL) 2 (MODEM)$' ; [19b] [gaw@prc]
- hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$'
- hnghlp db cr,lf,' The modem control lines DTR and RTS for the current'
- db ' port are forced low (off)'
- db cr,lf,' to hangup the phone. Normally, Kermit leaves them'
- db ' high (on) when it exits.'
- db cr,lf,'$'
- rdbuf db 80 dup (?) ; temp buf
- noimp db cr,lf,'?Not implemented.$'
- delstr db BS,' ',BS,'$' ; Delete string
- clrlin db cr,ESCAPE,'[0K','$'
- portin db 0 ; has clock int vector been initialized?
- xofsnt db 0 ; Say if we sent an XOFF.
- xofrcv db 0 ; Say if we received an XOFF.
- insrvc db false ; Say if in service on XON/XOFF interrupt
- parmsk db ? ; parity mask, 0ffh for no parity, 07f with.
- flowoff db ? ; flow-off char, Xoff or null (if no flow)
- flowon db ? ; flow-on char, Xon or null
- captrtn dw ? ; routine to call for captured output
- invseq db ESCAPE,'[7m$' ; Reverse video.
- nrmseq db ESCAPE,'[0m$' ; Normal mode.
- ivlseq db 79 dup (' '),cr,'$' ; Make a line inverse video
- tmp db ?,'$'
- temp dw 0
- temp1 dw ? ; Temporary storage.
- temp2 dw ? ; Temporary storage.
- fncerr db cr,lf,'Error on function '
- fnctype db 'X with a status return of '
- fncstat db 'Y$'
- argadr dw ? ; address of arg blk
-
- ; key redefinitions
- setktab db 0
-
- setkhlp db 0
-
- ; Entries for choosing communications port.
-
- comptab db 2 ; number of entries
- mkeyw 'Serial',1
- mkeyw 'Modem',2
-
-
-
- setchtab db 1; set file character-set table
- mkeyw 'CP437',437
-
-
- termtb db 6
- mkeyw '112x',ttsmall
- mkeyw '113x',ttbig
- mkeyw 'ANSI',ttgenrc
- mkeyw 'Tek4010',tttek
- mkeyw 'EnableTek',tekonnum
- mkeyw 'DisableTek', tekoffnum
- defbaud equ 7 ; defauld baud rate is 1200
-
-
- port1 prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
- port2 prtinfo <defbaud,0,defpar,1,0,defhand,floxon,0>
-
-
- portval dw port1 ; Default is to use port 1
-
- bdtab db 16 ; Baud rate table
-
- mkeyw '50',0
- mkeyw '75',1
- mkeyw '110',2
- mkeyw '134',3
- mkeyw '150',4
- mkeyw '300',5
- mkeyw '600',6
- mkeyw '1200',7
- mkeyw '1800',8
- mkeyw '2000',9
- mkeyw '2400',10
- mkeyw '3600',11
- mkeyw '4800',12
- mkeyw '7200',13
- mkeyw '9600',14
- mkeyw '19200',15
-
- modbdtab db 2 ; baud entries legal for modem
- mkeyw '300',5
- mkeyw '1200',7
-
-
-
- ; variables for serial interrupt handler
-
- gbuffer db gbuflen DUP(?) ; large internal buffer for grid [gaw@prc]
-
- source db bufsiz DUP(?) ; Buffer for data from port
- bufout dw 0 ; buffer removal ptr
- count dw 0 ; Number of chars in int buffer
- bufin dw 0 ; buffer insertion ptr
- telflg db 0 ; Are we acting as a terminal
- clreol db ESCAPE,'[0K$'
- blank db ESCAPE,'[2J$'
- movcur db ESCAPE,'['
- colno db 20 dup (?)
- ten db 10
- ourarg termarg <>
- keydelay dw 0 ;for periodically checking the keyboard
- clkdelay dw 0 ;check flow control every 4th tick
- serclk db false ;clock interrupt resets-for xon/xoff
- charout dd ? ; pointer to direct screen write [jan]
-
- savclko dw ? ; save clock tick interrupt vector offset
- savclks dw ? ; save clock tick interrupt vector segment
-
-
- data ends
-
- code segment public 'code'
- extrn comnd:near, dopar:near, defkey:near
- extrn sleep:near, msuinit:near, keybd:near
- extrn tekcls:near
- extrn tekemu:near ; entry point to msggri [jan]
- extrn sbrk:near ; memory allocator in mssker [jan]
- extrn srchkw:near, statc:near
- assume cs:code,ds:data
-
- ; local initialization
- lclini proc near
- mov dosnum,200h ; force dosnum to 2.00 so replay proc works
- mov prtrdy,true ; port is ready
- push es ;first set up for direct screen writing [jan]
- push bx ; See page A1 of the GRiD DOS Manual
- mov ax,0
- mov es,ax
- les bx,es:[200h] ; look in Bios for address of charout
- mov ax,es:[bx+20h] ; offset of charout in ax
- mov bx,es:[bx+22h] ; seg of charout routine in bx
- ; now store addr in a pointer that is used
- ; for indirect calls to charout
- mov word ptr charout,ax
- mov word ptr charout+2,bx
- pop bx ; restore the registers
- pop es
- ;we're all set up for direct screen write [jan]
- mov tekflg,0 ;tek emulator not initialized [jan]
- mov portin,0 ; serial port not yet initialized
- mov flags.vtflg,0 ; turn off terminal emulation [gaw@prc]
- call msuinit ; init keyboard translator
- call scrsavinit ;set up screen memory
- ; call serini ; initialize serial port
- ret
- lclini endp
-
- ;scrsavinit sets up memory block for saving tektronix and
- ; alpha screens two pages of screen memory are requested
- ; first page is for alpha, second is for tektronix
-
- scrsavinit proc near ;set up memory block to save [jan]
- push ax
- push cx
- push es
- push di
- mov ax,maxscnwrds*4+100 ; want 4*maxscnwrds bytes
- call sbrk ; ax will have the segment
- mov scrsavseg,ax ; put it in our data segment
- xor ax,ax ; ax=0--clear screen buffer
- mov di,ax ; di=0
- mov cx,2*maxscnwrds+6 ; number of words to be 0
- mov es,scrsavseg ; es points to memory segment
- rep stosw ; zero memory location [jrd]
- pop di
- pop es
- pop cx
- pop ax
- ret
- scrsavinit endp
-
-
- ; Clear the input buffer before sending a packet.
-
- CLRBUF PROC NEAR
- cmp repflg,0 ; doing replay?
- je clrb0 ; e => no replay
- ret ; don't clear if replaying
- clrb0:
- push ax ;need to save for CROSHAIR in msggri
- cli
- mov ax,offset source
- mov bufin,ax
- mov bufout,ax
- mov count,0
- sti
- clrb1: call prtchr ; get a character
- jnc clrb1 ; until there aren't any more
- pop ax
- clc
- ret
- CLRBUF ENDP
-
- ; Common routine to clear to end-of-line
-
- CLEARL PROC NEAR
- mov dx,offset clreol
- mov ah,prstr
- int dos
- ret
- CLEARL ENDP
-
-
- ; SHOW MODEM, displays current status of lines DSR, CD, and CTS.
- ; Uses byte mdmhand, the modem line status register. [jrd]
- shomodem proc near
- mov ah,cmcfm ; get a confirm
- call comnd
- jnc shomod0
- ret ; get out if error
- shomod0:
- mov dx,offset msmsg7 ; no modem status for network
- call getmodem ; get modem status
- mov mdmhand,al
- mov ah,prstr
- mov dx,offset msmsg1 ; modem ready msg
- test mdmhand,20h ; is DSR asserted?
- jz shomd1 ; z = no
- mov dx,offset msmsg2 ; say not asserted
- shomd1: int dos
- mov dx,offset msmsg3 ; CD asserted msg
- test mdmhand,80h ; CD asserted?
- jz shomd2 ; z = no
- mov dx,offset msmsg4 ; say not asserted
- shomd2: int dos
- mov dx,offset msmsg5 ; CTS asserted msg
- test mdmhand,40h ; CTS asserted?
- jz shomd3 ; z = no
- mov dx,offset msmsg6 ; say not asserted
- shomd3: mov ah,prstr
- int dos
- stc
- ret ; carry set upon failure
- shomodem endp
-
- ; Get modem status and set global byte mdmhand. Preserve all registers.
- ; status in al ; ax not preserved [jan]
-
- getmodem proc near
- push bx ;need to save everybody
- push cx
- push dx
- pushf
- mov ah,5 ;grid status call
- call grdfnc
- mov al,ah ;ah contains status if no error
- popf
- pop dx
- pop cx
- pop bx
- clc ; carry clear upon success
- ret
- getmodem endp
-
-
- ; Do a grid function call to the correct com port and return
-
- GRDFNC PROC NEAR
- or portbusy,1 ;so we know port is busy
- push es ; save es reg
- push ds ; then mov ds to es
- pop es
- push ax ; save function call and value in al
- add ah,"0" ; make function code printable
- mov fnctype,ah ; and save in error message
- pop ax ; restore ax
- cmp flags.comflg,1 ; serial port or modem? [gaw@prc]
- jne grdfnc1 ; if modem, do other int [gaw@prc]
- int gserial ; else do serial port function call [gaw@prc]
- jmp short grdfnc2 ; skip other int [gaw@prc]
- grdfnc1:int gmodem ; do modem port function call [gaw@prc]
- grdfnc2:jnc grdfnc3 ; skip error msg if carry not set
- add al,"0" ; make error code printable
- mov fncstat,al ; and put in error message
- mov ah,prstr
- push dx
- mov dx,offset fncerr ; Give an error message
- int dos
- pop dx
- grdfnc3:pop es ; restore es
- and portbusy,0feH ; clear bit 0
- ret
- GRDFNC ENDP
-
-
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns carry clear.
-
- BAUDST PROC NEAR
- saveregs
- mov dx,offset bdtab ; baud rate table for serial
- mov si,portval
- mov ax, offset port2 ; structure for modem
- cmp ax,si ; using the modem
- jne baudst1 ; ne= > yes, using modem
- mov dx, offset modbdtab
- baudst1:xor bx,bx ; help is the table itself
- mov ah,cmkey ; get keyword
- call comnd
- jc baudst2 ; c = failure
- push bx ; save result
- mov ah,cmeol ; get confirmation
- call comnd
- pop bx
- jc baudst2 ; c = failure
- mov si,portval ; get address of baud structure
- mov ax,[si].baud ; remember original value
- mov [si].baud,bx ; set the baud rate
- call dobaud ; use common code
- clc
- baudst2:restoreregs
- ret
- BAUDST ENDP
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns normally.
- ; illegal rate not checked; baudst does this
-
- DOBAUD PROC NEAR
- saveregs
- mov bx,portval
- mov ax,[bx].baud ; ax has baud rate from bdtab
- mov ah,gsbaud ; set up to set the port baudrate
- call grdfnc ; do a grid function call to a com port
- restoreregs
- ret
- DOBAUD ENDP
-
- ; Send a break out the current serial port. Returns normally.
- sendbr proc near
- push ax
- mov ax,250 ;250 milliseconds long
- call sendbrt ;do a timed break
- pop ax ;restore ax
- ret
- sendbr endp
-
- ; Send a long break out the current serial port. Returns normally.
- sendbl proc near
- push ax
- mov ax,1400 ;1400 milliseconds long
- call sendbrt ;do a timed break
- pop ax ;restore ax
- ret
- sendbl endp
-
- ;send timed break. ax has length in milliseconds.
- sendbrt proc near
- mov portbusy,2 ; port is occupied
- push cx ; save cx
- push ax ; save length of break
- mov ax,gbrkon ; setup to do break on [gaw@prc]
- call grdfnc ; do break on
- pop ax ; get time to delay
- call pcwait ; wait awhile
- mov ax,gbrkoff ; setup to do break off [gaw@prc]
- call grdfnc ; do break off
- mov ax,50
- call pcwait ; wait awhile
- pop cx ; restore
- mov portbusy,0 ; port no longer busy
- clc
- ret ; And return
- sendbrt endp
-
-
- ; Send char in ah out the serial port. Checks flow control.
- ; clc if success
- OUTCHR PROC NEAR
- push cx
- push bx
- cmp portin,0 ; port initialized?
- jne outchr0 ; ne=> not initialized
- call serini ; initialize port
- outchr0:
- mov bx,portval
- cmp [bx].floflg,0 ; Are we doing flow control
- pop bx
- je outch2 ; No, just continue
- xor cx,cx ; clear counter
- cmp ah,flowoff ; sending xoff?
- jne outch1 ; ne = no
- mov xofsnt,false ; supress xon from chkxon buffer routine
- outch1: cmp xofrcv,true ; Are we being held?
- jne outch2 ; No - it's OK to go on
- loop outch1 ; held, try for a while
- mov xofrcv,false ; timed out, force it off and fall thru
- outch2:
- mov al,ah ; parity routine expects character in al
- call dopar ; do the parity [jan ]
- mov byte ptr temp,al ; put character in buffer
- push di ; Save register
- mov cx,1 ; set up to write one char to a grid port
- mov di,offset temp
- mov ah,gwrite
- call grdfnc ; go write a character
- pop di ; restore saved registers
- pop cx
- clc
- ret ; clc means success
- OUTCHR ENDP
-
- ; This routine blanks the screen.
-
- CMBLNK PROC NEAR
- push ax
- push dx
- mov ah,prstr
- mov dx,offset blank
- int dos
- pop dx
- pop ax
- clc ; stay in connect mode
- ret
- CMBLNK ENDP
-
- LOCATE PROC NEAR
- mov dx,0 ; Go to top left corner of screen.
- jmp poscur ; callret...
- LOCATE ENDP
-
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port. Returns normally.
- ; This is used during initialization.
-
- GETBAUD PROC NEAR
- push ax ; save some regs
- push bx
- push cx
- push dx
- mov ah,ggbaud ; set up to get port baud rate
- call grdfnc ; and go get it
- mov al,ah ; mov baudrate into al
- mov ah,0 ; and zero upper part of ax
- mov bx,portval
- mov [bx].baud,ax ; Set baud rate
- pop dx ; restore regs
- pop cx
- pop bx
- pop ax
- clc ; msxibm does this
- ret
- GETBAUD ENDP
-
- ; Returns with char in al, # of chars in buffer in dx and carry clear.
- ; Carry set means no character available.
- PRTCHR PROC NEAR
- cmp repflg,0 ; doing replay?
- je prtch0a ; e => not doing replay
- jmp getrepchr ; get replay character if in replay
- prtch0a: cmp portin,0 ; port not initialized
- jne prtch0b ; 0=> not initialized
- call serini
- prtch0b:
- cmp serclk,true ; should we check flow control? [jan][jrd]
- jne prtch0 ;ne = no
- call flowchek ;checkout flow control
- prtch0: push si
- cmp count,0 ; any characters?
- jne prtch2 ; ne = yes, get from buffer
- prtch1:
- push di
- push bx
- push cx
- mov cx,bufsiz ; set up to read from grid port buffer
- mov di,offset source
- mov ah,gread
- call grdfnc
- pop cx ; restore saved registers
- pop bx
- pop di
-
- mov count,ax ; reset count
- or ax,ax
- jz prtch4 ; still no chars
- mov bufout,offset source ; this is output ptr
- prtch2:
- dec count
- mov dx,count ; return count in dx
- mov si,bufout
- cld
- lodsb ; get character
- mov bufout,si ; update ptr
- pop si
- clc ; clc means a character
- ret
- prtch4: pop si
- stc ; stc means no characters
- ret
- PRTCHR ENDP
-
- ;FLOWCHEK --Check to see if we need to do flow control
- ;this gets called in connect mode each 4 ticks of the clock
- ;both SERINT and PRTCHR call this. SERINT will not call FLOWCHEK
- ;if the port is busy
- ;
- ;
- FLOWCHEK PROC NEAR
- or portbusy,2 ;bit 1 set if in flowchek
-
- ; code below largely taken from old SERINT
- push ax
- push bx
- push cx
- push dx
- push di
- cld
- mov bx,portval
- cmp [bx].floflg,0 ; Doing flow control?
- je intdone ; No, just leave.
- mov ah,grstat ; get the buffer count
- call grdfnc
- cmp xofsnt,true ; Have we sent an XOFF?
- je flowchek1 ; Yes.
- cmp cx,mntrgh ; Past the high trigger point?
- jbe intdone ; No, we're within our limit
- mov ah,flowoff ; Get the XOFF
- or ah,ah ; null (no flow control)?
- jz intdone ; z = yes, do nothing
- mov byte ptr temp,ah ; put character in buffer
- mov cx,1 ; set up to write one char to a grid port
- mov di,offset temp
- mov ah,gwrite
- call grdfnc ; go write a character
- mov xofsnt,true ; Remember we sent it
- jmp intdone
-
- flowchek1:
- cmp cx,mntrgl ; below the low trigger point?
- ja intdone ; no, don't send XON
- mov ah,flowon ; get the XON
- or ah,ah ; null?
- jz intdone ; z = yes, do nothing
- mov byte ptr temp,ah ; put character in buffer
- mov cx,1 ; set up to write one char to a grid port
- mov di,offset temp
- mov ah,gwrite
- call grdfnc ; go write a character
- mov xofsnt,false ; remember we sent it
- intdone:pop di
- pop dx
- pop cx
- pop bx
- pop ax
- mov serclk,false
- mov portbusy,0 ;port no longer busy
- ret
- FLOWCHEK ENDP
-
- ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
- ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
- ; else repeat cycle. Requires that the port be initialized before hand.
- ; Ihosts is used by the local send-file routine just after initializing
- ; the serial port.
- ; 22 March 1986 [jrd]
-
- IHOSTS PROC NEAR
- push ax ; save the registers
- push bx
- push cx
- push dx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = none
- jz ihosts1 ; z = null
- call outchr ; send it (release Host's output queue)
- nop ; outchr can do skip return
- nop
- nop
- ihosts1:call clrbuf ; clear out interrupt buffer
- pop dx ; empty buffer. we are done here
- pop cx
- pop bx
- pop ax
- ret
- IHOSTS ENDP
-
- ; IHOSTR - initialize the remote host for our reception of a file by
- ; sending the flow-on character (XON typically) to release any held
- ; data. Called by receive-file code just after initializing the serial
- ; port. 22 March 1986 [jrd]
- IHOSTR PROC NEAR
- push ax ; save regs
- push bx
- push cx
- mov bx,portval ; port indicator
- mov ax,[bx].flowc ; put Go-ahead flow control char in ah
- or ah,ah ; don't send null if flow = none
- jz ihostr1 ; z = null
- call outchr ; send it (release Host's output queue)
- nop ; outchr can do skip return
- nop
- nop
- ihostr1:pop cx
- pop bx
- pop ax
- ret
- IHOSTR ENDP
-
- DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making
- ; DTR and RTS low.
- mov ah,cmtxt ; allow text to be able to display help
- mov bx,offset rdbuf ; dummy buffer
- mov dx,offset hnghlp ; help message
- call comnd ; get a confirm
- jnc dtrlow1
- ret ; get out if error
- dtrlow1:
- call serhng ; drop DTR and RTS
- mov ah,prstr ; give a nice message
- mov dx,offset hngmsg
- int dos
- clc
- ret ; clear carry for success
- DTRLOW ENDP
-
- ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
- ; to terminate the connection. 29 March 1986 [jrd]
- ; Calling this twice without intervening calls to serini should be harmless.
- ; Returns normally.
-
- SERHNG PROC NEAR ;[jan]
- or portbusy,2 ;port is occupied
- mov ax,150
- call pcwait ;wait for next tick of clock
- cmp flags.comflg,1 ;serial(1) or modem(<>1)
- jne serhngm ;jne means we are using modem
- mov ax,01000H ;turn off rts with function 16
- call grdfnc
- mov ax,100
- call pcwait ;wait 100 mx
- mov ax,01100H ;turn off dtr with function 17
- call grdfnc
- mov ax,500 ;wait 1/2 second
- call pcwait
- mov ax,010ffH ;turn on rts with function 16
- call grdfnc
- mov ax,100
- call pcwait
- mov ax,011ffH ;turn on dtr with function 17
- call grdfnc
- jmp serhng1
- serhngm: ;hang up modem
- mov ah,ginit
- call grdfnc ;hangup and initialize modem
- mov ax,500
- call pcwait ;let relay settle down
- mov prevport,86 ;fake so serini will initialize
- call serini ;this reinitialzes modem
- serhng1:mov ax,300 ;wait to let things settle
- call pcwait
- mov portbusy,0 ;port is no longer occupied
- clc ; success
- ret
- SERHNG ENDP
-
- MODEMSTR PROC NEAR ;send initializing string to modem [jan]
- cmp flags.comflg,2 ; using modem
- je modemstr0a ; yes
- ret ; get out if serial
- modemstr0a:
- push ax ;save ax
- mov ax,200
- call pcwait ;delay 200 ms before doing something
- push es ;save es and di
- push di
- push ds
- pop es ;es now points to our data segment
- mov di,offset mdmstr ;string to send to modem
- mov cx,mdmstrlen ;length of the string
- modemstr0: push cx ;save cx
- cmp byte ptr es:[di],',' ;delay 0.5 second on comma
- jne modemstr2
- mov ax,500 ;delay for the comma
- call pcwait
- jmp modemstr3 ;onto next character
- modemstr2:
- mov ax,50 ;send out port
- call pcwait ;50 ms between characters
- mov cx,1 ;1 byte at a time
- mov ah,2 ;grid write call
- call grdfnc ;write it to modem
- modemstr3: inc di ;point to next byte
- pop cx ;get the count
- loop modemstr0 ;do the next byte if cx<>0
- pop di ;restore di and es
- pop es
- pop ax
- ret
- MODEMSTR ENDP
-
- ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
- ; Based on 4.77 Mhz 8088 processor speeds.
- ; Thanks to Bernie Eiben for this one.
- pcwait proc near
- mov cx,240 ; inner loop counter for 1 millisecond
- pcwai1: sub cx,1 ; inner loop takes 20 clock cycles
- jnz pcwai1
- dec ax ; outer loop counter
- jnz pcwait ; wait another millisecond
- ret
- pcwait endp
-
-
- ; Position the cursor according to contents of DX.
-
- POSCUR PROC NEAR
- push ax ; save regs
- push dx
- push es
- push di
- mov ax,ds
- mov es,ax ; address data segment!!!
- cld
- mov di,offset colno
- mov al,dh ; row
- inc al ; adjust offset from 1 instead of 0
- mov ah,0 ; zero up half of reg containing number
- call nout
- mov al,';'
- stosb
- mov al,dl ; column
- inc al ; adjust offset from 1 instead of 0
- mov ah,0 ; zero up half of reg containing number
- call nout
- mov al,'H'
- stosb
- mov al,'$'
- stosb
- mov dx,offset movcur
- mov ah,prstr
- int dos ; print the sequence
- pop di
- pop es
- pop dx
- pop ax
- ret
- POSCUR ENDP
-
- ; put the number in ax into the buffer pointed to by di. Di is updated
- nout proc near
- push dx ; save registers
- push bx
- push ax
- cld
- mov dx,0 ; high order is always 0
- mov bx,10
- div bx ; divide to get digit
- push dx ; save remainder digit
- or ax,ax ; test quotient
- jz nout1 ; zero, no more of number
- call nout ; else call for rest of number
- nout1: pop ax ; get digit back
- add al,'0' ; make printable
- stosb ; drop it off
- pop ax ; restore all registers
- pop bx
- pop dx
- ret
- nout endp
-
-
- ; Write a line in inverse video at the bottom of the screen...
- ; the line is passed in dx, terminated by a $. Returns normally.
- putmod proc near
- push dx ; preserve message
- mov dx,26 * 100H ; line 26
- call poscur
- mov dx,offset invseq ; put into inverse video
- mov ah,prstr
- int dos
- pop dx
- int dos
- mov dx,offset nrmseq ; normal videw
- int dos
- ret ; and return
- putmod endp
-
- ; Clear the mode line written by putmod. Returns normally.
- clrmod proc near
- mov dx,26 * 100H
- call poscur
- call clearl
- ret
- clrmod endp
-
- ; Put a help message one the screen in reverse video. Pass
- ; the message in AX, terminated by a null. Returns normally.
- ; The message is put wherever the cursor currently is located.
- puthlp proc near
- push ax
- mov ah,prstr ; Leave some room before the message
- mov dx,offset crlf
- int dos
- pop si ; Put message address here
- puth0: mov ah,prstr
- mov dx,offset invseq ; Put into reverse video
- int dos
- mov ah,prstr
- mov dx,offset ivlseq ; Make line inverse video
- int dos
- cld
- puth1: lodsb
- cmp al,0 ; Terminated with a null
- je puth2
- mov dl,al
- mov ah,conout
- int dos
- cmp al,lf ; Line feed?
- je puth0 ; Yes, clear the next line
- jmp puth1 ; Else, just keep on writing
- puth2: mov dx,offset crlf
- mov ah,prstr
- int dos
- mov dx,offset nrmseq ; Normal video
- int dos
- clc
- ret
- puthlp endp
-
- ; Perform a delete.
-
- DODEL PROC NEAR
- push ax
- push dx
- mov ah,prstr
- mov dx,offset delstr ; Erase character
- int dos
- pop dx
- pop ax
- ret
- DODEL ENDP
-
- ; Perform a Control-U.
-
- CTLU PROC NEAR
- push ax
- push dx
- mov ah,prstr
- mov dx,offset clrlin
- int dos
- pop dx
- pop ax
- ret
- CTLU ENDP
- ;; set the current port
- COMS PROC NEAR
- mov dx,offset comptab
- xor bx,bx ; help is the table itself
- mov ah,cmkey
- call comnd
- jnc coms00
- ret ; get out if error
- coms00: push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jc comx ; carry set = failure
- pop bx
- mov flags.comflg,bl ; Set the comm port flag
- cmp flags.comflg,1 ; Using Com 1?
- jne coms0 ; ne = no
- mov portval,offset port1
- clc ; carry clear for success
- ret
- coms0: mov portval,offset port2
- clc ; carry clear for success
- ret
- comx: pop bx
- stc ; carry set for failure
- ret
- COMS ENDP
-
- ; Set heath emulation on/off.
-
- VTS PROC NEAR
- mov dx,offset termtb
- mov bx,0
- mov ah,cmkey
- call comnd
- jnc vts0
- ret ; get out if error
- vts0:
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm
- jc vt0 ; carry => didn't get a confirm
- pop bx
- cmp bl,ttbig ; using big screen?
- jne vt1 ;ne means its not big
- mov bigscreen,1 ; so we know screen is big
- mov screenbyte, bl ; for status
- mov scnwrds, 256*32 ; words in big screen
- mov tekflg,0 ; tek needs reinitialization
- clc
- ret
- vt1: cmp bl,ttsmall ;ne means its not small
- jne vt1a
- mov tekflg,0 ; tek needs reinitialization
- mov scnwrds, 240*20 ;words in small screen
- mov bigscreen,0 ;screen is not big, i.e. it's small
- mov screenbyte, bl ; for status
- clc
- ret
- vt1a: cmp bl,tekonnum ; enable tek?
- jne vt1b ; ne = no, don't enable
- and denyflg,not tekxflg ; clear tekx bit
- mov tekbyte,bl ; for status display
- clc
- ret
- vt1b: cmp bl,tekoffnum ; disable tek
- jne vt2 ; ne => don't disable
- or denyflg,tekxflg ; set tek deny bit
- mov tekbyte,bl ; for status display
- clc
- ret
-
-
- vt2: mov flags.vtflg,bl ; Set the Tektronix emulation flag [jan]
- mov tekflg,0 ; need to re-initialize tek emulator [jan]
- clc ; carry clear for success
- vt3: ret
- vt0: pop bx
- stc ; carry set for failure
- ret
- VTS ENDP
-
-
-
- VTSTAT PROC NEAR ; For Status display [jrd]
- mov bx, offset vtstbl ; table of things to show
- jmp statc ; common status code
- ;;; ret ; no emulator status to display
- VTSTAT ENDP
-
- termtog proc near ; toggle terminal type [jan]
- call savescr ; save present screen
- xor flags.vtflg,tttek ;toggle terminal type
- mov tekflg,0 ; we need to re-initialize tek emulator
- call restscr ; restore the previous screen
- clc ; do not exit Connect mode [jrd]
- ret
- termtog endp
-
- kclrscn proc near ; clear screen in text or Tek mode [jrd]
- cmp flags.vtflg,tttek ; doing Tek emulation?
- jne kclrsc1 ; ne = no
- call cmblnk ; blank for good measure [jan]
- call tekcls ; blank and some more
- clc ; stay in Connect mode
- ret
- kclrsc1:call cmblnk ; blank screen
- clc ; stay in Connect mode
- ret
- kclrscn endp
-
-
-
-
-
- ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
- ; Default filename is Kermit.scn; actual file can be a device too. Filename
- ; is determined by mssset and is passed as pointer dmpname.
-
- DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here
- call beep ; [jrd]
- clc
- ret
- DUMPSCR ENDP
-
-
-
- ; show the definition of a key. The terminal argument block (which contains
- ; the address and length of the definition tables) is passed in ax.
- ; Returns a string to print in AX, length of same in CX.
- ; Returns normally.
- showkey proc near
- ret ; and return
- showkey endp
-
-
- ; Common initialization for using serial port.
-
- SERINI PROC NEAR
-
- mov portbusy,2 ;port is occupied-don't check flow
- mov clkdelay,0 ; restart flow check clock
- push es
- cmp portin,0 ; Did we initialize interrupt already?
- je serin0 ; No, skip exit
- jmp serin1 ; Yes, so just leave
- serin0:
- cli ; Disable interrupts
- cld ; Do increments in string operations
- xor ax,ax ;ax=0
- mov es,ax ;es=0
- mov bx,CLK_INT ;clock vector
- mov ax,es:[bx] ;get offset
- mov savclko,ax ;save clock int offset
- mov ax,es:[bx+2] ;get segment
- mov savclks,ax ;save clock int segment
-
- mov ax,offset serint
- mov es:[bx],ax ; and load with offset of serint
- mov ax,cs
- mov es:[bx+2],ax ; and load with code segement address
- ;clk vector now reset
- mov portin,1 ; Remember interrupt has been initialized
- sti ; turn interrupts back on
- serin1: call getbaud ; get existing baud rate
- call dobaud ; and reset it
-
- push bx
- mov bx,portval ; get port
- mov parmsk,0ffh ; parity mask, assume parity is None
- cmp [bx].parflg,parnon ; is it None?
- je serin2 ; e = yes
- mov parmsk,07fh ; no, pass lower 7 bits as data
- serin2: mov bx,[bx].flowc ; get flow control chars
- mov flowoff,bl ; xoff or null
- mov flowon,bh ; xon or null
- pop bx
-
-
- mov ah,flags.comflg ;get new com port
- cmp ah,prevport ;port changed?
- je serin3 ;no change so don't reinitialize
- mov prevport,ah ;remember we have changed
- xor ax,ax
- mov ah,gspar ; parity = none
- call grdfnc
- mov al,1 ; stopbit = 1
- mov ah,gssbit
- call grdfnc
- mov al,8 ; data bits = 8
- mov ah,gsdata
- call grdfnc
- mov dx,1 ; timeout on char read wait = 1ms
- mov ah,gcharto
- call grdfnc
- call modemstr ; init modem if on
- cmp flags.comflg,1 ; Using Com 1?
- jne skipcts ; Nope.
- mov dx,0 ; timeout on cts = 0
- mov ah,gcts
- call grdfnc
- skipcts:mov ax,ds ; point to large buffer
- mov es,ax
- mov di,offset gbuffer
- mov cx,gbuflen
- mov ah,gbufass
- call grdfnc
- mov ah,gflush ; flush grid input buffer
- call grdfnc
- ;; call clrbuf ; Clear input buffer
- serin3: pop es
- mov portbusy,0 ;now able to do flow checking
- clc ; carry clear for success
- ret
- SERINI ENDP
-
-
- SERRST PROC NEAR ; reset the clock interrupt vector
- cmp portin,0 ; Did we initialize interrupt already?
- je serrst0 ; No, skip resetting clock vector
- cli ; Disable interrupts
-
- push es ; restore vector of clock tick int at 1CH
- xor ax,ax ; point to segment part of vector
- mov es,ax ; es=0
- mov bx,CLK_INT ; clock interrupt =1ch*4
- mov ax,savclko ; replace with original value
- mov es:[bx],ax ; restore offset
- mov ax,savclks
- mov es:[bx+2],ax ; restore segment
- pop es ; and clean up stack
- mov portin,0 ; Remember interrupt has been reset.
- sti ; turn interrupts back on
-
- serrst0:
- ret ; All done
- SERRST ENDP
-
-
- ; Comm port interrupt service routine to prevent grid buffer overflow
- ; Calls flowchek which sends Xoff if necessary if activated
- ;flow control is checked every 4 clock ticks, about 80 ms
- ; Modified by [jan] with helpful suggestions from [jrd]
- SERINT PROC FAR
- push ax ;all registers must be saved by SERINT
- push ds ;here, we put some words on the stack
- mov ax,data ;first we let the clock interrupt get called
- mov ds,ax ;then (maybe) come back to check flow control
- pop save_ds ;save ds
- pop save_ax ;save ax
- pushf ;save since they're changed by and instr.
- inc clkdelay ;just do flow control check
- mov ax,clkdelay ;once each 4 ticks of the clock
- and ax,3 ;for improved performance
- jnz serint0 ;nz means don't check this tick
- popf
- pushf ;restore flags and return to stack
- mov ax,cs ;put segment of return address on stack
- push ax ;clock will return here
- mov ax,offset serint1 ;offset of return address
- push ax ;is placed on stack
- pushf ;this will come off
- serint0:popf ;remove extra flags from stack
-
- mov ax,savclks ;put address of clock routine
- push ax ;on top of stack
- mov ax,savclko
- push ax
- mov ax,save_ax ;restore ax and ds
- mov ds,save_ds
- ret ;go to the clock routine
- ;we come back at serint1
- ;once each 4 ticks
- ;;Clock interrupt returns here if (clkdelay and 3)=0
-
-
- serint1: ;; entry point after clock routine
- push ax
- push bx
- push cx
- push dx
- push ds
- mov ax,data
- mov ds,ax
- mov serclk,true ;check out flow control at least once/4 tick
- cmp insrvc,true ; are we already doing interrupt service?
- je retint ; yes, then skip service until this one done
- mov insrvc,true ; nope, set in service flag
- cmp portbusy,0 ;is serial port available?
- jne serint5 ;don't stack calls
- ;grdfnc is non-reentrant
- sti ; flag set enable interrupts
- call flowchek ;do flow control checking
- mov serclk,false ;don't check until next tick
- serint5: mov insrvc,false ; set in service flag to false
- retint: pop ds
- pop dx
- pop cx
- pop bx
- pop ax
- iret ;iret since we have to remove flags
- SERINT ENDP
- ; Generate a short beep.
-
-
-
- BEEP PROC NEAR
- mov dl,bell
- mov ah,conout
- int dos
- ret
- BEEP ENDP
-
-
- ;check string to see if we need to do something special
-
- stringchek proc near
- cmp stringchekcnt,0 ; nobody in yet?
- jne stringchek1 ; ne => already have characters
- cmp al,escape ; is this escape?
- je stringchek1 ; it is escape, so go and process
- cmp al,escape+80h ; in case parity is odd
- je stringchek1 ; process the escape
- stc ; display the character
- ret ; return quickly if nothing to do
- stringchek1: ; here is escape already in
- saveregs
- and al,07fh ;strip high bit
- mov bx,stringchekcnt
- mov stringchekbuff[bx],al ;put character in buffer
- inc stringchekcnt ;one more character in buffer
- call stringtest ; does the string in stringchekbuff match?
- cmp match,0 ; 0 means no match
- je stringchek2
- mov si,match ; here means we have a match
- shl si,1 ; multiply by 2
- dec si
- dec si ; 1=0, 2=1 etc
- call disptab[si] ; call appropriate function
- call stringbuffplay ; play back the buffer
- clc ; don't display
- jmp stringchek3 ; return and don't display character
- stringchek2:
- clc ; don not display
- cmp matchsofar,true ; do we have a match so far
- je stringchek3 ; e=true , get out
- mov playem,true
- call stringbuffplay ; clean out the buffer
- clc ; don't display character
- stringchek3:
- restoreregs
- ret
- stringchek endp
-
- ;test to see if input string is a match to toggle terminal [jan]
-
-
- ; stringtab gives addresses of 0 terminated strings
- ; teststring in stringchekbuff
- ;numstrings is the number to checked
- ; matchsofar will have be true if there is a possilbe match
- ; match will be non-zero 1, 2, 3 indicating number of match if a match
- ; if no match yet, match will be 0
- ; severaal registers get destroyed
- stringtest proc near
- mov matchsofar, false ; assume no match
- mov match,0 ; no match
- xor si,si ; pointer to string tab
- dec si
- dec si ; step back 1 item
- mov cx,0 ; cx points to number of string
- strtst1:
- inc cx ; strings number
- cmp cx,numstrings ; done parsing table?
- ja strtst5 ; we're done, get out of here
- mov di, offset stringchekbuff
- inc si
- inc si ; point to next item
- mov bx,stringtab[si] ; offset of string
- strtst2:
- mov al,[di] ; stringchekbuff in al
- mov ah,[bx] ; string element to test in ah
- cmp al,0 ; end of stringchekbuff
- jne strtst2a ; ne=> not at end of buffer
- mov matchsofar,true ; we have a match so far
- jmp strtst5 ; return to caller
- strtst2a:
- cmp ah,0 ; at end of string?
- je strtst1 ; failure, go to next string
- cmp ah,al ; match?
- jne strtst1 ; no match, on to next string
- ; here if match
- mov ah,[bx+1] ; next byte from string
- cmp ah,0 ; are we done with string?
- je strtst3 ; e => yes, a match
- inc bx ; next element in string
- inc di ; next character in stringchekbuff
- jmp strtst2 ; check next item in string
- strtst3: ; here if we have a match
- mov match,cx ;
- mov matchsofar,true ;
- strtst5:
- ret
- stringtest endp
-
-
-
- ;play back characters in string buffer ..called by stringchek
- stringbuffplay proc near
- xor bx,bx ;bx=0
- mov cx,stringchekcnt
- stringbuffplay1:
- mov al,stringchekbuff[bx]
- cmp playem,true ;playback characters?
- jne stringbuffplay2 ;ne = no don't play back
- push bx ; save index
- push cx ; save count
- call outtty ; print the character
- pop cx ; restore count
- pop bx ; restore index
- stringbuffplay2:
- mov stringchekbuff[bx],0 ;set to 0
- inc bx ;point to next character
- loop stringbuffplay1 ;repeat until buffer is empty
- mov stringchekcnt,0 ;now no characters in buffer
- ret
- stringbuffplay endp
-
- ignoretek proc near ; ignore this escape sequence in tek mode
- mov playem,false
- cmp flags.vtflg,tttek ; are in in tek emulation
- je ignoretek1 ; e=yes do not play back
- mov playem,true
- ignoretek1:
- ret
- ignoretek endp
-
- ignoreall proc near ; always ignore this escape sequence
- mov playem,false
- call beep
- ret
- ignoreall endp
-
- totekplay proc near ; turn on tektronix
- mov playem,true ; play back characters
- jmp totek
- totekplay endp
-
- toteknoplay proc near
- mov playem,false
- jmp totek
- toteknoplay endp
-
-
- totek proc near ; turn on tektronix
- test denyflg,tekxflg ;tek auto entry enabled?
- jz totek1
- mov playem,true ; play back characters
- ret
- totek1:
-
- cmp flags.vtflg,tttek ; already doing tek
- je totek2
- call termtog ; toggle to tektronix
- totek2:
- ret
- totek endp
-
-
- ; put the character in al to the screen, do capture and printing,
- ; does translation for Set Input command.
- ; Adapted from msyibm.asm [jrd]
- outtty proc near
- cmp flags.vtflg,tttek ; doing tektronix emulation?
- jne outtty1 ; ne= not doing tek emulation
- jmp tekemu ; do tekemu and return
- outtty1:cmp repflg,0 ; replaying?
- je outtty2 ; e=> no replay
- ; mov ah,conout ; dostty screen mode
- ; mov dl,al ; write without intervention.
- ; int dos ; else let dos display char
- ; ret ; get out
- outtty2:
-
- test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp8 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp8: cmp rxtable+256,0 ; is translation off?
- je outnp7 ; e = yes, off
- push bx ; Translate incoming char [jrd]
- mov bx,offset rxtable ; address of translate table [jrd]
- xlatb ; new char is in al
- pop bx
- outnp7:
- test ourarg.flgs, capt ; capture flag on?
- jz outnoc ; no, forget this part
- push ax ; save char
- call captrtn ; give it captured character
- pop ax ; restore character and keep going
- outnoc: test ourarg.flgs,prtscr ; should we be printing?
- jz outnop ; no, keep going
- push ax
- mov ah,print_out ; write to system printer device
- mov dl,al
- int dos
- pop ax
- jnc outnop ; nc = successful print
- push ax
- call beep ; else make a noise and
- call trnprs ; turn off printing
- pop ax
- outnop: cmp flags.vtflg,0 ; emulating a terminal?
- jnz outnop1 ; nz = yup, go do something smart
- test ourarg.flgs,trnctl ; debug? if so use dos tty mode
- jz outnp5 ; z = no
- mov ah,conout
- cmp al,7fh ; Ascii Del char or greater?
- jb outnp1 ; b = no
- je outnp0 ; e = Del char
- push ax ; save the char
- mov dl,7eh ; output a tilde for 8th bit
- int dos
- pop ax ; restore char
- and al,7fh ; strip high bit
- outnp0: cmp al,7fh ; is char now a DEL?
- jne outnp1 ; ne = no
- and al,3fH ; strip next highest bit (Del --> '?')
- jmp outnp2 ; send, preceded by caret
- outnp1: cmp al,' ' ; control char?
- jae outnp3 ; ae = no
- add al,'A'-1 ; make visible
- outnp2: push ax ; save char
- mov dl,5eh ; caret
- int dos ; display it
- pop ax ; recover the non-printable char
- outnp3: mov dl,al
- int dos
- ret
- ;outnp4: ;cmp al,bell ; bell (Control G)? [jrd]
- ;jne outnp5 ; ne = no
- ; jmp beep ; use short beep, avoid char loss.
- outnop1:
- outnp5:
- call charout ;tell grid bios to write character[jan]
- ; mov ah,conout ; dostty screen mode
- ; mov dl,al ; write without intervention.
- ; int dos ; else let dos display char
- outnp6: ret ; and return
- outtty endp
-
- ; send the character in al out to the serial port
- ; handle echoing also...
- outprt proc near
- ; test flags,lclecho ; echoing?
- test ourarg.flgs,lclecho ; echoing?
- jz outpr1 ; no, forget it
- push ax ; save char
- call outtty ; print it
- pop ax ; restore
- outpr1: mov ah,al ; this is where outchr expects it
- call outchr ; output to the port
- nop
- nop
- nop ; skip returns
- ret
- outprt endp
-
- ; Get a char from the serial port manager
- ; returns with carry on if a character is available
- portchr proc near
- call prtchr ; character at port?
- jnc portc1 ; nc => character at port
- portc0: clc ; no carry -> no character
- ret ; and return
- portc1: and al,parmsk ; apply 8/7 bit parity mask
- stc ; have a character
- ret ; and return
- portchr endp
-
-
- argini proc near ; read passed arguments
- mov bx,argadr ; base of argument block
- mov ax,[bx].captr
- mov captrtn,ax ; buffer capture routine
- mov parmsk,0ffh ; parity mask, assume parity = None
- cmp [bx].parity,parnon ; is parity None?
- je argin2 ; e = yes, keep all 8 bits
- mov parmsk,07fh ; else keep lower 7 bits
- argin2: call serini ; initialize port if necessary
- ret ; that's it
- argini endp
-
- getflgs proc near
- mov al,ourarg.flgs ;supply flags for msggri [jan]
- ret
- getflgs endp
-
- term proc near
- mov argadr,ax ; save argument ptr
- push es
- mov si,ax ; this is source
- mov di,offset ourarg ; place to store arguments
- push ds
- pop es ; address destination segment
- mov cx,size termarg
- cld
- rep movsb ; copy into our arg blk
- pop es
- call argini ; init options from arg address
- cmp curini,0 ; have we been in here before[gaw@prc]
- je term1 ; if not skip restoring cursor[gaw@prc]
- call restscr ; restore screen
-
- term1: cmp prtrdy,false ; ready to read port
- je term5 ; get out
- call portchr ; read char from serial port
- jnc term3 ; nc = no char, go on
- cmp flags.vtflg,tttek ; doing tek emulation?
- je term1a ; e=yes, already doing tek
- call stringchek ; ESC FF will turn on tek [jan]
- jnc term3
- term1a: call outtty ; display and capture char [jrd]
-
- term3: inc keydelay ; just check keyboard once
- mov ax,keydelay ; each eight reads of the port
- and ax,7 ; should speed things up
- jnz term1 ; at higher baud rates [jan]
- call keybd ; call keyboard xlator, send results
- jnc term1 ; nc = stay in Connect mode
- term5: ; [gaw@prc]
- call savescr ; save screen [gaw@prc]
- cmp prtrdy,true ; need to set kbdflg if wierd exit
- je term6
- mov kbdflg,'C' ; so we exit connect mode
- mov prtrdy,true
- term6: ret
- term endp
-
-
- getrepchr proc near ; get replay character for file
- mov ah,readf2 ; read from replay file
- mov bx,diskio.handle
- mov cx,1 ; read 1 character
- mov dx,offset rdbuf ; to this buffer
- int dos
- jc getrepchr1 ; c => failure
- cmp ax,cx ; read the byte?
- jne getrepchr1
- mov al,rdbuf ; al has character
- clc ; character available in al
- clc
- ret
-
-
- getrepchr1:
- call beep ; announce file is done
- call beep
- call getkey ; wait for a key to be pressed
- mov prtrdy,false ; so we exit connect mode
- stc
- ret ; no character available
- getrepchr endp
-
- repchrout proc near ; process key in al while replaying
- and al,7fh ; strip parity
- repchrout1:
- cmp al,'C'-40h ; Control C?(to exit playback mode)
- je repchrout3 ; e=> yes, return failure
- cmp al,XOFF ; user wants to stop?
- jne repchrout2 ; ne => ok to continue
- call getkey ; wait and get a key
- jmp repchrout1 ; now process this key
- repchrout2:
- clc ; return success
- ret
- repchrout3:
- mov prtrdy,false ; exit terminal
- stc ; exit connect mode
- ret
- repchrout endp
-
- getkey proc near ; wait for a key to be typed
- mov ah,7
- int dos
- ret
- getkey endp
-
- savescr proc near
- push es ; move ds base address to es
- push di
- push ax
- push dx
- xor ax,ax
- mov di,maxscnwrds*2 ;tek page by default
- cmp flags.vtflg,tttek
- je savsc1
- mov di,0 ;point to 1st page for text
- mov ah,prstr ; send '<esc>[s' to ansi.sys[gaw@prc]
- mov dx,offset cursav ; [gaw@prc]
- int dos ; [gaw@prc]
- mov byte ptr curini,1 ; now we've saved the cursor[gaw@prc]
- mov dx,offset curoff ; turn off cursor
- mov ah,prstr
- int dos
-
-
- savsc1: mov ax,scrsavseg
- mov es,ax ;es points to screen save segment
- mov si,scnstrt ; point to screen memory area
- mov cx,scnwrds ; setup word count
- push ds
- xor ax,ax ; point to base page with ds
- mov ds,ax
- cld
- rep movsw ; transfer image to save area
- pop ds ; restore registers and return
- mov dx,offset curon ; turn on cursor
- mov ah,prstr
- int dos
- pop dx
- pop ax
- pop di
- pop es
- ret
- savescr endp
-
- restscr proc near
- mov dx,offset curoff ; turn off cursor
- mov ah,prstr
- int dos
- mov dx,offset blank ; clear screen to get rid of cursor
- mov ah,prstr
- int dos
- push es ; point to base page with es
- xor ax,ax ; restore screen
- mov es,ax
- xor ax,ax
- mov si,ax ;si=0 by default
- cmp flags.vtflg,tttek
- jne ressc1 ;ne means not tek
- mov si,maxscnwrds*2 ;point to second page if tek
-
-
- ressc1: mov di,scnstrt ; point to screen memory area
- mov cx,scnwrds ; setup word count
- mov ax,scrsavseg
- push ds
- mov ds,ax ;ds points to screen save area
- cld
- rep movsw ; transfer image to screen
- pop ds
- pop es
- cmp flags.vtflg,0 ; are we in emulation mode[gaw@prc]
- jne ressc2 ; to skip restoring cursor[gaw@prc]
- mov ah,prstr ; send '<esc>[u' to ansi.sys[gaw@prc]
- mov dx,offset curres ; [gaw@prc]
- int dos ; [gaw@prc]
- mov dx,offset curon ; turn on cursor
- mov ah,prstr
- int dos
- ressc2: ret
- restscr endp
-
-
- ; msu calls this to send keystroke in al out the port
- chrout proc near
- cmp repflg,0 ; in replay mode?
- je chrout1 ; e=> not doing replay
- jmp repchrout ; display the replay character
- chrout1:call outprt ; put char in al to serial port
- clc ; stay in Connect mode
- ret
- chrout endp
-
-
- trnprs: push ax ; toggle Copy screen to printer
- test ourarg.flgs,prtscr ; are we currently printing?
- jnz trnpr2 ; nz = yes, its on and going off
- mov ah,ioctl
- mov al,7 ; get output status of printer
- push bx
- mov bx,4 ; file handle for system printer
- int dos
- pop bx
- jc trnpr1 ; c = printer not ready
- cmp al,0ffh ; Ready status?
- je trnpr2 ; e = Ready
- trnpr1: call beep ; Not Ready, complain
- jmp trnpr3 ; and ignore request
- trnpr2: xor ourarg.flgs,prtscr ; flip the flag
- trnpr3: pop ax
- clc
- ret
-
-
- klogon proc near ; resume logging (if any)
- test flags.capflg,logses ; session logging enabled?
- jz klogn ; z = no, forget it
- or ourarg.flgs,capt ; turn on capture flag
- push bx ; tell kermit we resume logging
- mov bx, offset argadr
- or [bx].flgs, capt
- pop bx
- klogn: clc
- ret
- klogon endp
-
- klogof proc near ; suspend logging (if any)
- and ourarg.flgs, not capt
- push bx
- mov bx, offset argadr
- and [bx].flgs, not capt ; turn off kermit's capture flag
- pop bx
- klogo: clc
- ret
- klogof endp
-
- snull: mov ah,0 ; send a null
- call outchr ; send without echo or logging
- clc
- ret
-
- kdos: mov al,'P' ; Push to DOS
- jmp short cmdcom
- cstatus:mov al,'S' ; these commands exit Connect mode
- jmp short cmdcom
- cquit: mov al,'C'
- jmp short cmdcom
- cquery: mov al,'?'
- jmp short cmdcom
- cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
- stc ; say exit Connect mode
- ret
-
- code ends
- end
-